const DISTANCE = 100; // 动画距离
const DURATION = 500; // 动画时间
const map = new WeakMap();

const ob = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const animation = map.get(entry.target);
      animation?.play();
      ob.unobserve(entry.target);
    }
  });
})

// 判断元素是否在视窗内
function isBelowViewport(el: HTMLElement) {
  return el.getBoundingClientRect().top > window.innerHeight;
}

// 加载动画
const slideUp = {
  mounted(el: HTMLElement) {
    if (!isBelowViewport(el)) {
      return;
    }
    const animation = el.animate(
      [
        {
          transform: `translateY(${DISTANCE}px)`,
          opacity: 0.5
        },
        {
          transform: 'translateY(0)',
          opacity: 1
        }
      ],
      {
        duration: DURATION,
        easing: 'ease-out',
        fill: 'forwards'
      }
    );
    animation.pause();
    map.set(el, animation);
    ob.observe(el);
  },
  unmounted(el: HTMLElement) {
    ob.unobserve(el);
  }
};

// 加载动画
const slidePlus = {
  mounted(el: HTMLElement) {
    if (!isBelowViewport(el)) {
      return;
    }
    const animation = el.animate(
      [
        {
          transform: `scale(0.7) translateY(${DISTANCE}px)`,
          opacity: 0.5
        },
        {
          transform: 'scale(1) translateY(0)',
          opacity: 1
        }
      ],
      {
        duration: DURATION,
        easing: 'ease-out',
        fill: 'forwards'
      }
    );
    animation.pause();
    map.set(el, animation);
    ob.observe(el);
  },
  unmounted(el: HTMLElement) {
    ob.unobserve(el);
  }
};

// 文字渐显效果
const fadeIn = {
  mounted(el: HTMLElement) {
    if (!isBelowViewport(el)) {
      return;
    }
    const text = el.innerText.split('');
    let index = 0;
    el.innerHTML = '';
    const interval = setInterval(() => {
      if (index < text.length) {
        el.innerHTML += text[index];
        index++;
      } else {
        clearInterval(interval);
      }
    }, 10);
  }
}

export default {
  install(app: any) {
    app.directive('slide-up', slideUp);
    app.directive('slide-plus', slidePlus);
    app.directive('fade-in', fadeIn);
  }
};